import httpx,time
from .exception_base import *
from .log import get_logger
from .func_wrapper import *

HEADERS = {
    'User-Agent': r'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36 Edg/96.0.1054.53'
}

# MAX_RETRY=None
# req_logger=get_logger('Request')

class Request:
    # @classmethod
    # def _get(cls,url,*,headers=None,timeout=None,proxies=None):
    #     return httpx.get(url,headers=headers,timeout=timeout,follow_redirects=True,proxies=proxies)
    
    def __init__(self,*,max_retry=3,req_delay=0.3,timeout=None,proxy_repo=None,headers=None,logger=None) -> None:
        self.max_retry=max_retry
        self.req_delay=req_delay
        self.timeout=timeout
        self.proxy_repo=None
        self.headers=headers if headers else HEADERS
        self.proxy_repo=proxy_repo
        self.logger=logger if logger else get_logger('Request')
        self._last_req=-1
        self._try_get=None


    def _delay_request(self):
        if self.req_delay and (time.time()-self._last_req<self.req_delay):
            time.sleep(self.req_delay)  
        self._last_req=time.time()

    def _get_proxy(self):
        if not self.proxy_repo:
            return None
        return self.proxy_repo.get_proxy()

    def _get(self,url):
        self.logger.debug('Request for '+url)
        self._delay_request()

        proxy=self._get_proxy()   

        res=httpx.get(url,proxies=proxy,headers=self.headers,timeout=self.timeout,follow_redirects=True)

        if res.status_code==200:
            return res
        elif res.status_code==403:
            if not self.proxy_repo or self.proxy_repo.is_empty():
                self.logger.warn('Request was forbidden, stop requesting because no avaliable proxy!')
                raise StopRetry()
            self.proxy_repo.remove_proxy(proxy)
            raise ForbiddenRequestException('Request was forbidden!')
        else:
            raise Exception(f'Unexpected http code:{res.status_code}')
    
    def get(self,url):
        if self.max_retry<=1:
            return self._get(url)

        if not self._try_get:
            self._try_get=retry(self.max_retry,self.logger)(self._get)

        return self._try_get(url)

# DEFAULT_REQUEST=Request()